package com.zhixue.generator;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.Arrays;

/**
 * @author Dragon
 * @description AuthCodeGenerator
 * @date 2023/10/13 11:59
 */
public class AuthCodeGenerator {


    // TODO 修改服务名以及数据表名
    private static final String SERVICE_NAME = "users";

    //数据库账号
    private static final String DATA_SOURCE_USER_NAME  = "root";
    //数据库密码
    private static final String DATA_SOURCE_PASSWORD  = "123456";
    //生成的表
    private static final String[] TABLE_NAMES = new String[]{
            "oauth_access_token",
            "oauth_approvals",
            "oauth_client_details",
            "oauth_client_token",
            "oauth_code",
            "oauth_refresh_token",
            "zx_company",
            "zx_company_user",
            "zx_menu",
            "zx_permission",
            "zx_role",
            "zx_teacher",
            "zx_user",
            "zx_user_role"
    };

    // TODO 默认生成entity，需要生成DTO修改此变量
    // 一般情况下要先生成 DTO类 然后修改此参数再生成 PO 类。
    private static final Boolean IS_DTO = false;

    public static void main(String[] args) {
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();
        // 选择 freemarker 引擎，默认 Velocity
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        gc.setFileOverride(true);
        //生成路径
        gc.setOutputDir(System.getProperty("user.dir") + "/zhixue-generator/src/main/java");
        gc.setAuthor("Dragon");
        gc.setOpen(false);
        gc.setSwagger2(false);
        gc.setServiceName("%sService");
        gc.setBaseResultMap(true);
        gc.setBaseColumnList(true);

        if (IS_DTO) {
            gc.setSwagger2(true);
            gc.setEntityName("%sDTO");
        }
        mpg.setGlobalConfig(gc);

        // 数据库配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setDbType(DbType.MYSQL);
        dsc.setUrl("jdbc:mysql://192.168.234.128:3306/zx_" + SERVICE_NAME
                + "?serverTimezone=UTC&useUnicode=true&useSSL=false&characterEncoding=utf8");
//		dsc.setDriverName("com.mysql.jdbc.Driver");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername(DATA_SOURCE_USER_NAME);
        dsc.setPassword(DATA_SOURCE_PASSWORD);
        mpg.setDataSource(dsc);

        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName(SERVICE_NAME);
        pc.setParent("com.zhixue");
        pc.setService("service");
        pc.setController("controller");
        pc.setMapper("mapper");
        //以上都是默认的。只有下面的需要配置
        pc.setServiceImpl("service.impl");
        pc.setXml("mapper");
        pc.setEntity("model.po");
        mpg.setPackageInfo(pc);


        // 设置模板
        TemplateConfig tc = new TemplateConfig();
        mpg.setTemplate(tc);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);  //将数据库表名的下划线转换为驼峰命名法
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);    //将数据库字段名的下划线转换为驼峰命名法。
        strategy.setEntityLombokModel(true);    //生成的实体类使用 Lombok 注解来简化代码
        strategy.setRestControllerStyle(true);    //生成的 Controller 类使用 REST 风格。
        strategy.setInclude(TABLE_NAMES);     //指定要生成的表名
        strategy.setControllerMappingHyphenStyle(true);   //Controller 类的请求映射路径使用连字符分隔 @RequestMapping("/content/course-base")

        //strategy.setTablePrefix(pc.getModuleName() + "_");
        //strategy.setTablePrefix(pc.getModuleName() + "_"): 设置数据库表名的前缀，生成的实体类和相关代码中将去除该前缀,
        // 例如，如果模块名为 sys，表名为 sys_user，那么生成的实体类的类名将为 User，而不是 SysUser。

        strategy.setEntityBooleanColumnRemoveIsPrefix(false);
        // Boolean类型字段是否移除is前缀处理  生成的实体类中的布尔类型字段将移除 is 前缀
        // 例如，如果数据库表中有一个名为 is_deleted 的布尔字段，生成的实体类中该字段的名称将变为 deleted
        // 只限于使用框架，它会自己去匹配 ，而我觉得一般不要这样，容易造成自己写的sql语句出现找不到的问题


        // 自动填充字段配置
        strategy.setTableFillList(Arrays.asList(
                new TableFill("create_date", FieldFill.INSERT),
                new TableFill("change_date", FieldFill.INSERT_UPDATE),
                new TableFill("modify_date", FieldFill.UPDATE)
                //TableFill 对象指定了字段名为 "create_date"
                // 填充方式为 FieldFill.INSERT，表示在插入记录时会自动填充该字段的值。
                // 字段将自动填充为当前时间。
                // 通过配置字段的自动填充规则，可以简化开发过程中对这些字段的处理。无需手动设置这些字段的值，框架会根据配置的规则自动填充
                // 这些填充规则仅在使用框架提供的插入和更新方法时才会生效。如果直接使用原始的 SQL 插入或更新数据，填充规则可能不会生效。

        ));
        mpg.setStrategy(strategy);

        mpg.execute();
    }
}
